#pragma once


//-----------------------------------------------------------------------------
//	val (in/out) - value to smooth
//	val_rate (in/out) - rate of change
//	target (in) - desired target
//	time_delta (in) - time elapsed from last call
//	speed (in) - smoothing time
//-----------------------------------------------------------------------------
template<typename T>
void Smooth(T& val, T& val_rate, T target, float time_delta, float smooth_time)
{
	assert(smooth_time >= 0);
	assert(time_delta >= 0);

	if (smooth_time == 0)
	{
		val_rate = 0;
		val = target;
	}
	else if (time_delta > 0)
	{
		float omega = 2.0f / smooth_time;
		float x = omega * time_delta;
		float exponent = 1.0f/(1.0f + x + 0.48f*x*x + 0.235f*x*x*x);
		
		T change = val - target;
		float temp = (val_rate + change*omega)*time_delta;

		val_rate = static_cast<T>((val_rate - temp*omega)*exponent);
		val = static_cast<T>(target + (change + temp)*exponent);
	}
}